
/*
 * @项目名称: 模板开发
 * @FilePath: \meek\src\components\draw.js
 * @Author: 
 * @Date: 2017-03-23T11:12:12+08:00
 * @LastEditors: kongxueyang@datatang.com
 * @LastEditTime: 2023-08-15 09:53:09
 * Copyright (c) 2018-2022
 */

/**
 * Created by zypc on 2016/11/15.
 */

import Component from './component'
import { Style } from '../style/style'
import FeaureLayer from '../lyr/featurelayer'
import Feature from '../meek/feature'
import Geometry from '../geometry/geometry'
import Point from '../geometry/point'
import Line from '../geometry/line'
import Polygon from '../geometry/polygon'
import MultiPolygon from '../geometry/mutilpolygon'
import Extent from '../geometry/extent'
import Cube from '../geometry/cube'
import Trapezium from "../geometry/trapezium"
import { CubeUtil } from '../geometry/support/cubeutil'
import { ExtentUtil } from '../geometry/support/extentutil'
import { simplify } from '../geometry/support/geometryutil'
import { listen, unlistenByKey } from '../core/eventmanager'
import BrowserEvent from '../meek/browserevent'
import DrawEvent from './drawevent'
import Parallelogram from '../geometry/parallelogram'
import TiltRectangle from '../geometry/tiltrectangle'
import SquareX from '../geometry/squarex'
import { functions } from '../utils/functions'
import Circle from './../geometry/circle';
import Ellipse from './../geometry/ellipse';
import { distance } from './../geometry/support/geometryutil';
import PointStyle from './../style/pointstyle';
import FillStyle from './../style/fillstyle';
import LineStyle from './../style/linestyle';
import { feature } from '@turf/turf'


/**
 * 图形绘制工具基础类
 *
 * @class Draw
 * @extends Component
 * @module component
 * @constructor
 * @example
 *
 *      // 实例化绘图工具
 *      var drawTool = new Datatang.Draw({
 *        type: 'point',
 *        drawLayer: new Datatang.FeatureLayer()
 *      })
 *
 */
export default class Draw extends Component {

  /**
   * 构造函数
   *
   * @constructor constructor
   * @param options
   */
  constructor(options = {}) {
    super()

    this.applyHandleEventOption({
      handleDownEvent: this._handleDownEvent,
      handleMouseEvent: this.handleMouseEvent,
      handleUpEvent: this._handleUpEvent
    })

    /**
     * mapRenderKey
     * @type {null}
     * @private
     */
    this._mapRenderKey = null

    /**
     * 绘制作用图层;
     * 需要给绘制工具一个绘制的图层
     *
     * @property drawLayer
     * @type {null}
     * @private
     */
    this._drawLayer = options.drawLayer ? options.drawLayer : null

    /**
     * 鼠标按下时的坐标点
     *
     * @property downPointPx
     * @type {null}
     * @private
     */
    this._downPointPx = null

    /**
     * 图形绘制结束条件
     *
     * @property finishCoordinate
     * @type {null}
     * @private
     */
    this._finishCoordinate = null

    /**
     * 当前的绘图模式(点、线、多边形、矩形)
     *
     * @property drawMode
     * @type {*}
     */
    this.drawMode = Draw.getDrawMode(options.type)

    /**
     * 绘制多边形、线段时的临时坐标数据
     *
     * @property sketchCoords
     * @type
     * @private
     */
    this._sketchCoords = null

    /**
     * 绘制多边的临时线段
     *
     * @property sketchLine
     * @type {null}
     * @private
     */
    this._sketchLine = null

    /**
     * 绘制完成时的结束条件
     *
     * @property finishCondition
     * @type {null}
     * @private
     *
     */
    this._finishCondition = options.finishCondition ?
      options.finishCondition : functions.TURE

    /**
     * 撤销条件
     *
     * @property undoCondition
     * @type {Function}
     * @private
     */
    this._undoCondition = options.undoCondition !== undefined ?
      options.undoCondition : functions.TURE

    /**
     * 设置默认回退的顶点数，默认1
     * @TODO 需要完善
     * @type {number}
     * @private
     */
    this._undoStep = options.freehandUndoStep ?
      options.freehandUndoStep : 2

    // add keyboard events
    if (options.undoCondition || options.finishCondition) {
      listen(document, 'keyup',
        this._handleKeyboardEvent, this)
    }

    /**
     * 初始化草稿图层，用于临时显示绘制的图形
     *
     * @property sketchLayer
     * @type {Object} featurelayer
     * @private
     */
    this._sketchLayer = new FeaureLayer({ name: 'sketch layer for draw component' })

    /**
     * 获取默认绘制渲染样式
     *
     * @property sketchLayer
     * @private
     * @type {Function}
     */
    this._sketchLayer.style = this.getDefaultStyleFunction()

    /**
     * 临时点
     *
     * @property sketchPoint
     * @type {null}
     * @private
     */
    this._sketchPoint = null

    /**
     * 绘制时，是否允许鼠标参考点
     * @type {boolean}
     * @private
     */
    this._enableSketchPoint = options.enableSketchPoint ?
      options.enableSketchPoint : false

    /**
     * 临时Feature
     *
     * @property sketchFeature
     * @type {null}
     * @private
     */
    this._sketchFeature = null

    /**
     * （梯形）绘制参考线
     */
    this._referLineFeature = null
    this._referLineFeature2 = null

    /**
     * 通过geometry的类型去构建一个geometry
     *
     * @property eometryFunction
     * @type {null}
     * @private
     */
    // The function that can build a geometry by the passed geometry type.
    this._geometryFunction = null

    /**
     * 临时的线段坐标数据
     *
     * @property sketchLineCoords
     * @type {null}
     * @private
     */
    this._sketchLineCoords = null

    /**
     * freehand drawing
     * @type {Boolean}
     * @private
     */
    this._freehand = options.freehand ? options.freehand : false

    this._longPress = options.longPress ? options.longPress : false
    /**
     * 公差像素距离
     *
     * @property snapTolerance
     * @type {Number}
     * @private
     */
    this._snapTolerance = options.snapTolerance ?
      options.snapTolerance : 2

    /**
     * 绘制线段时的最多点限制，默认没有限制
     *
     * @property maxLinePoints
     * @type {Number}
     * @private
     */
    this._maxLinePoints = options.maxLinePoints ?
      options.maxLinePoints : Infinity

    /**
     * 绘制多边形时的顶点限制，默认没有限制
     *
     * @property maxPolygonPoints
     * @type {Number}
     * @private
     */
    this._maxPolygonPoints = options.maxPolygonPoints ?
      options.maxPolygonPoints : Infinity

    /**
     * 绘制线段的最少点为2，多边形为3
     *
     * @property minPoints
     * @type {Number}
     * @private
     */
    this._minPoints = options.minPoints ?
      options.minPoints :
      (this.drawMode === Draw.DrawMode.POLYGON ? 3 : 2)


    /**
     *
     * @type {condition}
     * @private
     */
    this._condition = options.condition ?
      options.condition : functions.TURE
    /**
     *
     * @type {boolean}
     * @private
     */
    this._shouldHandle = false
    /**
     *
     * @type {boolean}
     * @private
     */
    this._shouldExtentHandle = false


    /**
     *
     * @type {number}
     * @private
     */
    this._squaredClickTolerance = options.clickUpTolerance ?
      options.clickUpTolerance * options.clickUpTolerance : 36


    this._displayExtentLwText = options.displayExtentLwText !== undefined ? options.displayExtentLwText : true

    this._extentLwTextStyle = new PointStyle(
      8,
      [0, 0, 0],
      0,
      new FillStyle(
        [0, 0, 0],
        new LineStyle(
          [0, 0, 0],
          1,
          1.25
        ),
        0
      )
    );


  }

  /**
   * 处理绘制结束事件
   *
   * handleKeyboardEvent
   * @type {Function}
   * @param event {event}
   * @private
   */
  _handleKeyboardEvent(event) {
    // If finish drawing
    if (this._finishCondition(event)) {
      // 判断多边形的顶点是否小于4个（正常多边形3个顶点，首尾相接多一个顶点），小于4个不是多边形，return
      if (this.drawMode === Draw.DrawMode.POLYGON) {
        if (this._sketchFeature === null) {
          return
        }

        let pcoordinates = this._sketchFeature.geometry.getCoordinates()
        if (pcoordinates[0].length < 4) {
          return
        }
      }

      // 判断线的顶点是否小于2个，小于2个不是线段，return
      if (this.drawMode === Draw.DrawMode.LINE) {
        if (this._sketchFeature === null) {
          return
        }

        let pcoordinates = this._sketchFeature.geometry.getCoordinates()
        if (pcoordinates.length <= 2) {
          return
        }
      }
      //判断斜矩形
      if (this.drawMode === Draw.DrawMode.TILTRECTANGLE) {
        if (this._sketchFeature === null) {
          return
        }

        let pcoordinates = this._sketchFeature.geometry.getCoordinates()
        if (pcoordinates[0].length < 4) {
          return
        }
      }

      this._finishDrawing()
    }

    // If undo drawing
    if (this._undoCondition) {
      if (this._undoCondition(event)) {
        this._undoDrawing()
      }
    }
  }

  /**
   * 获取图形创建、修改的工厂方法
   *
   * @property geometryFunction
   * @type {Function}
   * @retruns geometryFunction {Function}
   */
  get geometryFunction() {
    if (!this._geometryFunction) {
      this._geometryFunction = this._initGeometryFunction()
    }

    return this._geometryFunction
  }

  /**
   * drawMode读写器，
   * 设置当前绘图的模式，重新赋值将会启动新图形类型的绘制
   *
   * @type {Function}
   * @property drawMode
   * @type {Datatang.Draw.DrawMode}
   */
  get drawMode() { return this._drawMode }
  set drawMode(value) {
    const isIn = this._existInDrawMode(value)

    this.active = isIn ? true : false
    this._drawMode = isIn ? value : Draw.DrawMode.UNDEFINED

    this._sketchLineCoords = null
    this._abortDrawing()

    this._minPoints = this._drawMode === Draw.DrawMode.POLYGON ? 3 : 2
  }

  /**
   * 判断传入的绘制类型是否在绘制列表中
   *
   * @method existInDrawMode
   * @param value {String}
   * @returns {Boolean}
   * @private
   */
  _existInDrawMode(value) {
    if ((typeof value === 'string') && (value.constructor === String)) {
      const drawMode = Draw.DrawMode
      const modeValue = value.toUpperCase()

      if (modeValue === Draw.DrawMode.UNDEFINED.toUpperCase()) {
        return false
      }

      for (let val in drawMode) {
        if (modeValue === drawMode[val].toUpperCase()) {
          return true
        }
      }
    }

    return false
  }

  /**
   * 图形生产工厂方法
   *
   * @method geometryFactory
   * @returns {Object} 返回一个geometry对象
   * @private
   */
  _geometryFactory() {
    let Constructor
    let mode = this.drawMode

    if (mode === Draw.DrawMode.POINT) {
      Constructor = Point
    } else if (mode === Draw.DrawMode.LINE) {
      Constructor = Line
    } else if (mode === Draw.DrawMode.POLYGON) {
      Constructor = Polygon
    } else if (mode === Draw.DrawMode.EXTENT) {
      Constructor = Extent
    } else if (mode === Draw.DrawMode.CUBE) {
      Constructor = Cube
    } else if (mode === Draw.DrawMode.PARALLELOGRAM) {
      Constructor = Parallelogram
    } else if (mode === Draw.DrawMode.TILTRECTANGLE) {
      Constructor = TiltRectangle
    } else if (mode === Draw.DrawMode.TRAPEZIUM) {
      Constructor = Trapezium
    } else if (mode === Draw.DrawMode.SQUAREX) {
      Constructor = SquareX
    } else if (mode === Draw.DrawMode.CIRCLE) {
      Constructor = Circle;
    } else if (mode === Draw.DrawMode.ELLIPSE) {
      Constructor = Ellipse;
    }

    return Constructor
  }

  /**
   * 设置缺省 geometryfunction
   *
   * @method initGeometryFunction
   * @returns {Function} Geometry
   * @private
   */
  _initGeometryFunction() {
    const geometryFunction = (coordinates, opt_geometry) => {
      let mode = this.drawMode
      let geometry = opt_geometry

      if (geometry) {
        if (
          mode === Draw.DrawMode.POLYGON ||
          mode === Draw.DrawMode.PARALLELOGRAM ||
          mode === Draw.DrawMode.TILTRECTANGLE ||
          mode === Draw.DrawMode.LINE ||
          mode === Draw.DrawMode.TRAPEZIUM ||
          mode === Draw.DrawMode.SQUAREX ||
          mode === Draw.DrawMode.CIRCLE ||
          mode === Draw.DrawMode.ELLIPSE
        ) {
          geometry.setCoordinates(coordinates)
        } else if (mode === Draw.DrawMode.EXTENT) {
          geometry.setCoordinates(ExtentUtil.boundingExtent(coordinates))
        } else if (mode === Draw.DrawMode.CUBE) {
          // geometry.setCoordinates(ExtentUtil.boundingExtent(coordinates))
          geometry.setCoordinates(CubeUtil.boundingCube(coordinates))
        }
      } else {
        let Constructor = this._geometryFactory()
        if (mode === Draw.DrawMode.POLYGON || mode === Draw.DrawMode.CIRCLE || mode === Draw.DrawMode.ELLIPSE) {
          geometry = new Constructor(coordinates);
        } else if (mode === Draw.DrawMode.CUBE) {
          geometry = new Constructor(coordinates[0], coordinates[1]);
        } else {
          geometry = new Constructor(coordinates[0], coordinates[1]);
        }
      }

      return geometry
    }

    return geometryFunction
  }

  /**
   * 或者 freehand draw 的执行条件
   *
   * @param event
   * @returns {boolean|*}
   * @private
   */
  _freehandEnable() {
    const drawMode = this.drawMode
    return (drawMode === Draw.DrawMode.POLYGON ||
      drawMode === Draw.DrawMode.LINE) && this._freehand
  }

  /**
   * 处理鼠标事件
   *
   * handleMouseEvent
   * @param event {event}
   * @returns {*|Boolean}
   */
  handleMouseEvent(event) {
    // 排除右键
    const buttons = event.originalEvent.buttons
    // if (buttons === 2) {
    //   return false
    // }
    // 越界限制
    event.coordinate = this.autoAdsorbent(this.coordinateBeyond(event));
    const freehand = this._freehandEnable()
    // this._freehand = this._freehandEnable()
    // let pass = !this._freehand
    let pass = true
    const eventType = event.type
    if (freehand &&
      eventType === BrowserEvent.MOUSE_DRAG &&
      this._sketchFeature !== null) {
      //防止freehand右键不能移动图片
      if (buttons === 2) {
        pass = true;
      } else {
        this._addToDrawing(event)
      }
      // pass = false
    } else if (eventType === BrowserEvent.MOUSE_MOVE) {
      pass = this._handleMove(event)
    } else if (eventType === BrowserEvent.DBLCLICK) {
      // 支持双击事件
      pass = true
    }

    return super.handleMouseEvent(event) && pass
  }

  /**
   * 处理移动事件
   *
   * handleMove
   * @param {BrowserEvent} event A move event.
   * @return {boolean} Pass the event to other compoments.
   * @private
   */
  _handleMove(event) {
    this._moveEvent = event
    if (this._downPointPx &&
      ((!this._freehand && this._shouldHandle) ||
        (this._freehand && !this._shouldHandle) || (!this._freehand && !this._shouldExtentHandle))) {
      const downPx = this._downPointPx
      const clickPx = event.pixel
      const dx = downPx[0] - clickPx[0]
      const dy = downPx[1] - clickPx[1]
      const squaredDistance = dx * dx + dy * dy
      this._shouldHandle = this._freehand ?
        squaredDistance > this._squaredClickTolerance :
        squaredDistance <= this._squaredClickTolerance
      if ((this.mode === Draw.DrawMode.Extent || this.mode === Draw.DrawMode.CUBE) && event.type === BrowserEvent.MOUSE_MOVE && this._longPress) {
        this._shouldExtentHandle = true;
      }
    }
    const coordinates = this._sketchCoords;
    if(this.drawMode === Draw.DrawMode.TILTRECTANGLE && event.type === BrowserEvent.MOUSE_MOVE && !this._drawLayer.showRefLine) {
      this._referLineFeature = null;
      this._referLineFeature2 = null;
    } else {
      this._referLineFeature2 = null;
    }
    if(this.drawMode === Draw.DrawMode.TILTRECTANGLE && event.type === BrowserEvent.MOUSE_MOVE && this._drawLayer.showRefLine) {
      if (coordinates && coordinates[0].length > 1) {
        const lines = TiltRectangle.getRefLineCoords(coordinates[0][0], coordinates[0][1]);
        this._referLineFeature = new Feature(new Line());
        this._referLineFeature2 = new Feature(new Line());
        this._referLineFeature.geometry.setCoordinates(lines[0])
        this._referLineFeature2.geometry.setCoordinates(lines[1])
      }
    }

    if (this._finishCoordinate) {
      this._modifyDrawing(event)
      // this._autoPan(event)
    } else {
      this._updateSketchPoint(event)
    }

    return true
  }

  /**
   * 鼠标按下时，获取当前坐标点
   *
   * handleDownEvent
   * @param event {BrowserEvent} event A up event.
   * @returns {Boolean}
   * @private
   */
  _handleDownEvent(event) {
    const button = event.originalEvent.button
    if (button !== 0) {
      return
    }
    if (!this._finishCoordinate) {
      if (!this.autoAdsorbent(this.coordinateBeyond(event, true))) {
        this._abortDrawing();
        return;
      }
    }
    //this._shouldHandle = !this._freehand
    this._shouldHandle = true
    if (this._freehand) {
      this._downPointPx = event.pixel
      if (!this._finishCoordinate) {
        this._startDrawing(event)
      }

      return true
    } else if (this._condition(event)) {
      if ((this.drawMode === Draw.DrawMode.EXTENT || this.drawMode === Draw.DrawMode.CUBE) && this._longPress) {
        this._downPointPx = event.pixel
        if (!this._finishCoordinate) {
          this._startDrawing(event)
          this._handleMove(event);
        }
        return true;
      } else {
        this._downPointPx = event.pixel
        return true
      }
    } else {
      return false
    }
  }

  /**
   * 处理鼠标弹起事件
   *
   * handleUpEvent
   * @param event {BrowserEvent} event
   * @private
   */
  _handleUpEvent(event) {
    if (this.drawMode === Draw.DrawMode.UNDEFINED) {
      return
    }
    const button = event.originalEvent.button
    if (button !== 0) {
      return
    }
    if (!this._finishCoordinate) {
      if (!this.autoAdsorbent(this.coordinateBeyond(event, true))) {
        this._abortDrawing();
        return;
      }
    }
    let pass = true
    const mode = this.drawMode
    if ((mode === Draw.DrawMode.EXTENT || mode === Draw.DrawMode.CUBE) && this._longPress) {
      if (this._shouldExtentHandle) {
        this._finishDrawing();
        this._shouldExtentHandle = false;
        this._downPointPx = null;
        return;
      } else {
        this._abortDrawing();
        this._downPointPx = null;
        this._shouldExtentHandle = false;
        return;
      }
    } else {
      this._handleMove(event)
    }

    if (this._shouldHandle) {
      if (!this._finishCoordinate) {
        this._startDrawing(event)

        // 点绘制在up的时候结束
        if (this.drawMode === Draw.DrawMode.POINT) {
          this._finishDrawing()
        }
      } else if (mode === Draw.DrawMode.CIRCLE || mode === Draw.DrawMode.ELLIPSE) {
        if (mode === Draw.DrawMode.ELLIPSE) {
          this._sketchFeature.geometry = this._sketchFeature.endGeometry;
        }
        this._finishDrawing()
      } else if (mode === Draw.DrawMode.EXTENT || mode === Draw.DrawMode.CUBE) {
        // this._finishDrawing()
        if (this._finishCondition(event)) {
          this._finishDrawing()
        }
      }
      else if (this._atFinish(event)) {
        if (this._finishCondition(event)) {
          this._finishDrawing()
        }
      } else {
        this._addToDrawing(event)
      }
    } else if (this._freehand && !this._finishCondition) {
      this._finishCoordinate = null
      this._abortDrawing()
    }

    return pass
  }

  /**
   * 启动绘制，生成feature
   *
   * @method startDrawing
   * @param event {Event}
   * @private
   */
  _startDrawing(event) {
    const startPoint = event.coordinate
    this._finishCoordinate = startPoint

    const _drawMode = this.drawMode

    // 构造geometry数据
    if (_drawMode === Draw.DrawMode.POINT) {
      this._sketchCoords = startPoint.slice() // 缓存up的点
    } else if (_drawMode === Draw.DrawMode.POLYGON) {
      this._sketchCoords = [[startPoint.slice(), startPoint.slice()]]
      this._sketchLineCoords = this._sketchCoords[0]// temp line
    } else if (_drawMode === Draw.DrawMode.PARALLELOGRAM) {// 平行四边形
      this._sketchCoords = [[startPoint.slice(), startPoint.slice()]]
      this._sketchLineCoords = this._sketchCoords[0]// temp line
    } else if (_drawMode === Draw.DrawMode.TILTRECTANGLE) {// 斜矩形
      this._sketchCoords = [[startPoint.slice(), startPoint.slice()]]
      this._sketchLineCoords = this._sketchCoords[0]// temp line
    } else if (_drawMode === Draw.DrawMode.TRAPEZIUM) {// 梯形
      this._sketchCoords = [[startPoint.slice(), startPoint.slice()]]
      this._sketchLineCoords = this._sketchCoords[0]// temp line
    } else if (_drawMode === Draw.DrawMode.SQUAREX) {
      this._sketchCoords = [[startPoint.slice(), startPoint.slice()]]
      this._sketchLineCoords = this._sketchCoords[0]// temp line
    } else if (_drawMode === Draw.DrawMode.CIRCLE) {
      this._sketchCoords = [startPoint[0], startPoint[1], 0];
    } else if (_drawMode === Draw.DrawMode.ELLIPSE) {
      this._sketchCoords = [startPoint[0], startPoint[1]];
    } else {
      this._sketchCoords = [startPoint.slice(), startPoint.slice()] // 缓存up的点，最后一个值，用于move的替换

      if (_drawMode === Draw.DrawMode.EXTENT || _drawMode === Draw.DrawMode.CUBE || _drawMode===Draw.DrawMode.LINE) {
        this._sketchLineCoords = this._sketchCoords
      }
    }
    if (this._sketchLineCoords) {
      this._sketchLine = new Feature(new Line(this._sketchLineCoords))
    }

    if (_drawMode === Draw.DrawMode.TRAPEZIUM) {
      const coords = Trapezium.getRefLineCoords(
        this._sketchCoords[0],
        this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
      )
      this._referLineFeature = new Feature(new Line());
      this._referLineFeature.geometry.setCoordinates(coords);
    } else if(_drawMode === Draw.DrawMode.SQUAREX) {
      const coords = SquareX.getRefLineCoords(
        this._sketchCoords[0],
        this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
      )
      this._referLineFeature = new Feature(new Line());
      this._referLineFeature.geometry.setCoordinates(coords);
    } else if(_drawMode === Draw.DrawMode.LINE) {
      if([2, 3].includes(Line.lineMode)){
        let coords
        if(Line.lineMode === 2) {
          coords = Line.getVerticalRefLineCoords(
            this._sketchCoords[0],
            this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
          )
        } else {
          coords = Line.getHorizontalRefLineCoords(
            this._sketchCoords[0],
            this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
          )
        }
        this._referLineFeature = new Feature(new Line())
        this._referLineFeature.geometry.setCoordinates(coords)
      } else {
        this._referLineFeature = null
        this._referLineFeature2 = null
      }
    } else {
      this._referLineFeature = null;
      this._referLineFeature2 = null;
    }
    let geometry = this.geometryFunction(this._sketchCoords);
    // Build a geometry uesed sketchCorrdds
    if (_drawMode === Draw.DrawMode.ELLIPSE) {
      this._sketchCoords = [startPoint.slice(), startPoint.slice()]
      geometry = new Extent(startPoint[0], startPoint[1]);
    }

    this._sketchFeature = new Feature()
    this._sketchFeature.geometry = geometry
    if (_drawMode === Draw.DrawMode.ELLIPSE) {
      this._sketchFeature.endGeometry = this.geometryFunction(startPoint);
    }
    // Redraw the sketch features
    this._updateSketchFeatures()

    this._shouldExtentHandle = false;

    // 派发绘制开始事件
    // Trigger the draw-strat event
    this.dispatchEvent(new DrawEvent(DrawEvent.EventType.DRAW_START, this._sketchFeature))
  }

  /**
   * Modify the drawing
   *
   * @param event {Event}
   * @private
   */
  _modifyDrawing(event) {
    let coordinate = event.coordinate
    const geometry = this._sketchFeature.geometry
    let coordinates = null, last = null
    const mode = this.drawMode

    if (mode === Draw.DrawMode.POINT) {
      last = this._sketchCoords

      last[0] = coordinate[0]
      last[1] = coordinate[1]
    } else if (mode === Draw.DrawMode.POLYGON) {
      coordinates = this._sketchCoords[0]
      last = coordinates[coordinates.length - 1]
      if (this._atFinish(event)) {
        coordinate = this._finishCoordinate.slice()
      }

      // 在鼠标移动的时候，将最后一个点替换成当前的鼠标点
      last[0] = coordinate[0]
      last[1] = coordinate[1]
    } else if (mode === Draw.DrawMode.TRAPEZIUM) {
      coordinates = this._sketchCoords[0]
      last = coordinates[coordinates.length - 1]
      if (this._atFinish(event)) {
        coordinate = this._finishCoordinate.slice()
      }

      // 在鼠标移动的时候，将最后一个点替换成当前的鼠标点
      last[0] = coordinate[0]
      last[1] = coordinate[1]
      const coord = geometry.getNextPoint(coordinates);
      if (coord) {
        coordinates[coordinates.length - 1] = coord
      }
    } else if (mode === Draw.DrawMode.SQUAREX) {
      coordinates = this._sketchCoords[0]
      last = coordinates[coordinates.length - 1]
      if (this._atFinish(event)) {
        coordinate = this._finishCoordinate.slice()
      }
      // 在鼠标移动的时候，将最后一个点替换成当前的鼠标点
      last[0] = coordinate[0]
      last[1] = coordinate[1]
      const coord = geometry.getNextPoint(coordinates);
      if (coord) {
        coordinates[coordinates.length - 1] = coord
      }
    } else if (mode === Draw.DrawMode.PARALLELOGRAM) {
      coordinates = this._sketchCoords[0]
      last = coordinates[coordinates.length - 1]

      // 需要清理，第三个点应该为鼠标点
      if (coordinates.length > 3) {
        coordinates = coordinates.slice(0, 2)
        coordinates.push(coordinate)
      } else {
        last[0] = coordinate[0]
        last[1] = coordinate[1]
      }

      const lastSecondPoint = coordinates[coordinates.length - 2]

      // 平行四边形，如果有3个点，则直接生成平行四边形
      if (coordinates.length === 3) {
        const lstPoint = Parallelogram.getTheLastPoint(coordinates)
        coordinates.push(lstPoint, coordinates[0])
        this._sketchCoords = [coordinates]

        // 辅助效果线
        this._sketchLineCoords = coordinates
      }

    } else if (mode === Draw.DrawMode.TILTRECTANGLE) {
      coordinates = this._sketchCoords[0]
      last = coordinates[coordinates.length - 1]
      // 需要清理，第三个点应该为鼠标点
      if (coordinates.length > 3) {
        coordinates = coordinates.slice(0, 2)
        coordinates.push(coordinate)
      } else {
        last[0] = coordinate[0]
        last[1] = coordinate[1]
      }

      const lastSecondPoint = coordinates[coordinates.length - 2]
      // 斜矩形，如果有3个点，则直接生成平行四边形
      if (coordinates.length === 3) {
        const threePoint = TiltRectangle.getThethreePoint(coordinates)//需要修改
        coordinates[2] = threePoint
        let lstPoint
        if (this.map.allowCoordinatesBeyondImage) {
          lstPoint = TiltRectangle.getTheLastPoint(coordinates)//需要修改
        } else {
          lstPoint = TiltRectangle.getTheLastPoint(coordinates, this.map.view._dataExtent)//需要修改

        }
        //const lstPoint = TiltRectangle.getTheLastPoint(coordinates, this.map.view._dataExtent)//需要修改
        coordinates = lstPoint
        this._sketchCoords = [coordinates]

        // 辅助效果线
        this._sketchLineCoords = coordinates
      }

    } else if(mode === Draw.DrawMode.CIRCLE) {
      let newR = Circle.getDistance([this._sketchCoords[0], this._sketchCoords[1]], coordinate);
      if (!this.map.allowCoordinatesBeyondImage) {
        let extent = this.map.view._dataExtent;
        if (
          this._sketchCoords[0] - newR >= 0 &&
          this._sketchCoords[0] + newR <= extent[2] &&
          this._sketchCoords[1] - newR >= 0 &&
          this._sketchCoords[1] + newR <= extent[3]
        ) {
          this._sketchCoords[2] = newR;
        } else {
          let r1 = this._sketchCoords[0];
          let r2 = extent[2] - this._sketchCoords[0];
          let r3 = this._sketchCoords[1];
          let r4 = extent[3] - this._sketchCoords[1];
          this._sketchCoords[2] = Math.min.apply(null, [r1, r2, r3, r4]);
        }
      } else {
        this._sketchCoords[2] = newR;
      }
      if (this._sketchCoords[2] <= 0) {
        this._sketchCoords[2] = 0.1;
      }
    } else if(mode === Draw.DrawMode.ELLIPSE) {
      // 椭圆
      this._sketchCoords[1][0] = coordinate[0];
      this._sketchCoords[1][1] = coordinate[1];
      this._sketchFeature.endGeometry.updateCoord(
        this._sketchCoords,
        this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
      );
    } else {
      coordinates = this._sketchCoords // 获取up的点
      last = coordinates[coordinates.length - 1]// 替换为当前MOve的点，形成一条path

      if(mode === Draw.DrawMode.LINE && Line.lineMode!==1){
        if(Line.lineMode===2){
          last[0] = coordinates[0][0]
          last[1] = coordinate[1]
        } else if(Line.lineMode===3){
          last[0] = coordinate[0]
          last[1] = coordinates[0][1]
        }
      } else {
        last[0] = coordinate[0]
        last[1] = coordinate[1]
      }
    }

    /*
    if (this._freehand) {
      const tempLastRing = this._sketchCoords[0]
      if (tempLastRing.length > 2) {
        const lastPoint = tempLastRing[tempLastRing.length - 1]
        const lastPoint2 = tempLastRing[tempLastRing.length - 2]

        if (lastPoint[0] === lastPoint2[0] && lastPoint[1] === lastPoint2[1]) {
          tempLastRing.pop()
        }
      }
    }
    */

    // 给 geometry 赋值

    if(mode === Draw.DrawMode.ELLIPSE) {
      geometry.setCoordinates(ExtentUtil.boundingExtent(this._sketchCoords))
    } else {
      this.geometryFunction(this._sketchCoords, geometry)
    }

    // 更新点坐标
    if (this._sketchPoint) {
      const sketchPointGeom = this._sketchPoint.geometry
      sketchPointGeom.update(coordinate[0], coordinate[1])
    }

    let sketchLineGeom
    if (mode === Draw.DrawMode.EXTENT || mode === Draw.DrawMode.CUBE) {
      if (!this._sketchLine) {
        this._sketchLine = new Feature(new Line(null))
      }

      const rings = geometry.getCoordinates()
      sketchLineGeom = this._sketchLine.geometry
      sketchLineGeom.path = rings
    } else if (this._sketchLineCoords) {
      sketchLineGeom = (this._sketchLine.geometry)
      sketchLineGeom.path = this._sketchLineCoords
    }

    this._updateSketchFeatures()
    if (this._displayExtentLwText) {
      if (mode === Draw.DrawMode.EXTENT || mode === Draw.DrawMode.TILTRECTANGLE) {
        this.addlwText()
      }
    }

  }


  addlwText() {
    try {
      let coords = this._sketchFeature.geometry.getCoordinates()
      if (this._sketchFeature.geometry.geometryType === Geometry.TILTRECTANGLE) {
        coords = coords[0]
      }
      const createPoint = (p1, p2) => {
        let c = [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2]
        const feature = new Feature(new Point(...c), {}, '', [this._extentLwTextStyle])
        feature.displayText = distance(p1, p2).toFixed(2)
        return feature
      }
      const createArea = (f1, f2, point) => {
        if (!f1 || !f2) {
          return
        }
        const feature = new Feature(new Point(...point), {}, '', [this._extentLwTextStyle])
        feature.displayText = 'area：' + (Number(f1.displayText) * Number(f2.displayText)).toFixed(2)
        return feature
      }
      const features = []
      if (coords[0] && coords[1]) {
        const f1 = createPoint(coords[0], coords[1])
        features.push(f1)
      }
      if (coords[1] && coords[2]) {
        const f2 = createPoint(coords[1], coords[2])
        features.push(f2)
      }
      const areaFeature = createArea(features[0], features[1], coords[3])
      areaFeature && features.push(areaFeature)
      this._sketchLayer.addFeatures(features)
    } catch (error) {

    }
  }
  /**
   * Add a new coordinate to the drawing
   *
   * @param event
   * @private
   */
  _addToDrawing(event) {
    const coordinate = event.coordinate
    const geometry = this._sketchFeature.geometry
    let coordinates, done
    const mode = this.drawMode

    if (mode === Draw.DrawMode.LINE) {
      this._finishCoordinate = coordinate.slice()
      coordinates = this._sketchCoords
      const last = coordinates[coordinates.length - 2];
      if (last && last[0] === coordinate[0] && last[1] === coordinate[1]) {
        return;
      }

      if (coordinates.length > this._maxLinePoints) {
        if (this._freehand) {
          coordinates.pop()
        } else {
          done = true
        }
      }

      // if (this._freehand) {
      //   if (coordinates.length > 1) {
      //     const lastPoint = coordinates[coordinates.length - 1]
      //     if (lastPoint[0] === coordinate[0] &&
      //       lastPoint[1] === coordinate[1]) {
      //       coordinates.pop()
      //     }
      //   }
      // }

      coordinates.push(coordinate.slice())
      this.geometryFunction(coordinates, geometry)
    } else if (mode === Draw.DrawMode.POLYGON) {
      coordinates = this._sketchCoords[0]
      const last = coordinates[coordinates.length - 2];
      if (last && last[0] === coordinate[0] && last[1] === coordinate[1]) {
        return;
      }

      if (coordinates.length > this._maxPolygonPoints) {
        if (this._freehand) {
          coordinates.pop()
        } else {
          done = true
        }
      }

      coordinates.push(coordinate.slice())

      if (done) {
        this._finishCoordinate = coordinates[0]
      }

      this.geometryFunction(this._sketchCoords, geometry)
    } else if (mode === Draw.DrawMode.PARALLELOGRAM) {
      coordinates = this._sketchCoords[0]

      // 当前坐标数组添加新点数组
      coordinates.push(coordinate.slice())
      done = coordinates.length > this._maxPolygonPoints

      if (done) {
        this._finishCoordinate = coordinates[0]
      }

      this.geometryFunction(this._sketchCoords, geometry)
    } else if (mode === Draw.DrawMode.TILTRECTANGLE) {
      coordinates = this._sketchCoords[0]

      // 当前坐标数组添加新点数组
      coordinates.push(coordinate.slice())
      done = coordinates.length > this._maxPolygonPoints

      if (done) {
        this._finishCoordinate = coordinates[0]
      }

      this.geometryFunction(this._sketchCoords, geometry)
    } else if (mode === Draw.DrawMode.TRAPEZIUM) {
      coordinates = this._sketchCoords[0]
      coordinates.push(coordinate.slice())
      const nextPoint = geometry.getNextPoint(coordinates)
      if (nextPoint) {
        coordinates.splice(-1, nextPoint)
      }

      done = coordinates.length > 4

      if (done) {
        this._finishCoordinate = coordinates[0]
      }

      this.geometryFunction(this._sketchCoords, geometry)
    } else if (mode === Draw.DrawMode.SQUAREX) {
      coordinates = this._sketchCoords[0]
      coordinates.push(coordinate.slice())
      const nextPoint = geometry.getNextPoint(coordinates)
      if (nextPoint) {
        coordinates.splice(-1, nextPoint)
      }

      done = coordinates.length > 4

      if (done) {
        this._finishCoordinate = coordinates[0]
      }

      this.geometryFunction(this._sketchCoords, geometry)
    }

    if (mode === Draw.DrawMode.TRAPEZIUM) {
      const coords = Trapezium.getRefLineCoords(
        coordinates,
        this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
      )
      if (coords) {
        this._referLineFeature.geometry.setCoordinates(coords);
        this._referLineFeature.display = true;
      } else {
        this._referLineFeature.display = false;
      }
    }
    if (mode === Draw.DrawMode.SQUAREX) {
      const coords = SquareX.getRefLineCoords(
        coordinates,
        this.map.allowCoordinatesBeyondImage ? null : this.map.view._dataExtent
      )
      if (coords) {
        this._referLineFeature.geometry.setCoordinates(coords);
        this._referLineFeature.display = true;
      } else {
        this._referLineFeature.display = false;
      }
    }

    this._updateSketchFeatures()

    if (done) {
      this._finishDrawing()
    }
  }


  /**
   * 终止绘制，不会添加临时feature
   *
   * @method abortDrawing
   * @returns {Feature|null|_Feature2.default}
   * @private
   */
  _abortDrawing() {
    this._finishCoordinate = null
    const sketchFeature = this._sketchFeature
    if (sketchFeature) {
      this._sketchFeature = null
      this._sketchPoint = null
      this._sketchLine = null
      this._sketchLayer.clear()
    }

    return sketchFeature
  }

  /**
   * 绘制完成，形成正式feature
   *
   * @method finishDrawing
   * @private
   */
  _finishDrawing() {
    if (this._sketchFeature === null) {
      this.dispatchEvent(new DrawEvent(DrawEvent.EventType.DRAW_END))
      return
    }

    const sketchFeature = this._abortDrawing()// 中止绘制，
    const coordinates = this._sketchCoords
    const geometry = (sketchFeature.geometry)

    const drawMode = this.drawMode

    if (drawMode === Draw.DrawMode.LINE) {
      // remove the redundant last point
      coordinates.pop()
      this.geometryFunction(coordinates, geometry)
    } else if (drawMode === Draw.DrawMode.POLYGON || drawMode === Draw.DrawMode.TRAPEZIUM || drawMode === Draw.DrawMode.SQUAREX) {
      // When we finish drawing a polygon on the last point,
      // the last coordinate is duplicated as for LineString
      // we force the replacement by the first point
      coordinates[0].pop()
      coordinates[0].push(coordinates[0][0])
      this.geometryFunction(coordinates, geometry)
    }

    // 处理复合图形
    if (drawMode === Geometry.MULTI_POINT) {
      // sketchFeature.geometry = new MultiPoint([coordinates]))
    } else if (drawMode === Geometry.MULTI_LINE) {
      // sketchFeature.geometry = new MultiLineString([coordinates])
    } else if (drawMode === Geometry.MULTI_POLYGON) {
      sketchFeature.geometry = new MultiPolygon([coordinates])
    }

    //if (this._freehand) {
    // simplify(sketchFeature.geometry)
    //}
    // 最终放到shource中，形成正式feature
    if (this._drawLayer) {
      sketchFeature.style = undefined
      this._drawLayer.addFeatures([sketchFeature])
    }
    // First dispatch event to allow full set up of feature
    this.dispatchEvent(new DrawEvent(DrawEvent.EventType.DRAW_END, sketchFeature))
  }

  /**
   * Determine if an event is within the snapping tolerance of the start coord.
   *
   * @param event
   * @returns {Boolean}
   * @private
   */
  _atFinish(event) {
    let at = false
    if (this._sketchFeature) {

      if (this._freehand && this._finishCondition) {
        return false
      }

      let potentiallyDone = false
      let potentiallyFinishCoordinates = [this._finishCoordinate]

      const drawMode = this.drawMode
      if (drawMode === Draw.DrawMode.LINE) {
        potentiallyDone = this._sketchCoords.length > this._minPoints
      } else if (drawMode === Draw.DrawMode.POLYGON) {
        potentiallyDone = this._sketchCoords[0].length > this._minPoints
        potentiallyFinishCoordinates = [this._sketchCoords[0][0],
        this._sketchCoords[0][this._sketchCoords[0].length - 2]]
      } else if (drawMode === Draw.DrawMode.PARALLELOGRAM) {
        at = this._sketchCoords[0].length === 5 ? true : false
      } else if (drawMode === Draw.DrawMode.TILTRECTANGLE) {
        at = this._sketchCoords[0].length === 5 ? true : false
      } else if (drawMode === Draw.DrawMode.TRAPEZIUM) {
        at = this._sketchCoords[0].length === 5 ? true : false
      } else if (drawMode === Draw.DrawMode.SQUAREX) {
        at = this._sketchCoords[0].length === 5 ? true : false
      }

      if (potentiallyDone) {
        const map = event.map
        for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) {
          const finishCoordinate = potentiallyFinishCoordinates[i]
          const finishPixel = map.getPixelFromCoordinate(finishCoordinate)
          const pixel = event.pixel
          const dx = pixel[0] - finishPixel[0]
          const dy = pixel[1] - finishPixel[1]
          const freehand = this._freehand
          const snapTolerance = freehand ? 1 : this._snapTolerance
          at = Math.sqrt(dx * dx + dy * dy) <= snapTolerance
          if (at) {
            this._finishCoordinate = finishCoordinate
            break
          }
        }
      }
    }

    return at
  }

  /**
   * Create or update the sketch point
   *
   * updateSketchPoint
   * @param event {BrowserEvent} event
   * @private
   */
  _updateSketchPoint(event) {
    let coordinates = event.coordinate

    if (!this._enableSketchPoint) {
      return
    }

    if (this._sketchPoint === null) {
      const geom = new Point(coordinates[0], coordinates[1])
      this._sketchPoint = new Feature(geom)
      this._updateSketchFeatures()
    } else {
      const sketchPointgeom = this._sketchPoint.geometry
      sketchPointgeom.setCoordinates(coordinates)
    }
  }

  _autoPan(event) {
    const pixel = event.pixel
    const size = this.map.size
    const x = pixel[0]
    const y = pixel[1]

    if (x <= 2 || y <= 2) {
      // console.log('出界')
      return
    }

    if (x >= size[0] - 5 || y >= size[1] - 5) {
      // console.log('出界')
      return
    }

  }

  /**
   * Redraw the sketch featrues.
   * updateSketchFeatures
   * @private
   */
  _updateSketchFeatures() {
    const features = []

    if (this._sketchFeature) {
      features.push(this._sketchFeature)
    }

    if (this._sketchLine) {
      features.push(this._sketchLine)
    }

    if (this._sketchPoint) {
      features.push(this._sketchPoint)
    }

    if (this._referLineFeature) {
      features.push(this._referLineFeature)
      this._referLineFeature.style = this.getDefaultStyleFunction()(this._referLineFeature);
      this._referLineFeature.style.splice(-1);
      this._referLineFeature.style.forEach(s => {
        s.style = "dash";
        s.color = [230, 162, 60];
      });
    }

    if (this._referLineFeature2) {
      features.push(this._referLineFeature2)
      this._referLineFeature2.style = this.getDefaultStyleFunction()(this._referLineFeature2);
      this._referLineFeature2.style.splice(-1);
      this._referLineFeature2.style.forEach(s => {
        s.style = "dash";
        s.color = [230, 162, 60];
      });
    }

    // 出发map的render
    this._sketchLayer.clear()
    this._sketchLayer.addFeatures(features)
  }

  /**
   * 执行撤销
   *
   * @method undoDrawing
   * @private
   */
  _undoDrawing() {
    const drawMode = this.drawMode
    let undoStep = 1
    let polygonDeleteStep = 2
    /*
    if (this._freehand) {
      undoStep = this._undoStep
      polygonDeleteStep = 3
    }*/

    if (drawMode === Draw.DrawMode.LINE) {
      if (this._sketchFeature) {
        const coordinates = this._sketchFeature.geometry.getCoordinates()
        if (coordinates.length + undoStep > 3) {
          coordinates.splice(coordinates.length - 2, undoStep)
          this._sketchFeature.changed()
        } else {
          this._abortDrawing()
          this._finishDrawing()
        }
      }
    } else if (drawMode === Draw.DrawMode.POLYGON) {
      if (this._sketchFeature) {
        const pcoordinates = this._sketchFeature.geometry.getCoordinates()[0]
        if (pcoordinates.length + undoStep > polygonDeleteStep + 1) {
          pcoordinates.splice(pcoordinates.length - polygonDeleteStep, undoStep)
          this._sketchFeature.changed()
        } else {
          this._abortDrawing()
          this._finishDrawing()
        }
      }
    } else if ([Draw.DrawMode.CIRCLE, Draw.DrawMode.ELLIPSE, Draw.DrawMode.EXTENT, Draw.DrawMode.CUBE].includes(drawMode)) {
      if (this._sketchFeature) {
        this._abortDrawing()
        this._finishDrawing()
      }
    } else if ([Draw.DrawMode.PARALLELOGRAM, Draw.DrawMode.TILTRECTANGLE].includes(drawMode)) {
      if (this._sketchFeature) {
        const coordinates = this._sketchFeature.geometry.getCoordinates()[0]
        if (coordinates.length >= 3) {
          coordinates.length = 2
          this._sketchFeature.changed()
          this._moveEvent && this._handleMove(this._moveEvent)
        } else {
          this._abortDrawing()
          this._finishDrawing()
        }
      }
    }  else if ([Draw.DrawMode.TRAPEZIUM].includes(drawMode)) {
      if (this._sketchFeature) {
        const pcoordinates = this._sketchFeature.geometry.getCoordinates()[0]
        if (pcoordinates.length + undoStep > polygonDeleteStep + 1) {
          pcoordinates.splice(pcoordinates.length - polygonDeleteStep, undoStep)
          this._sketchFeature.changed()
          this._moveEvent && this._handleMove(this._moveEvent)
        } else {
          this._abortDrawing()
          this._finishDrawing()
        }
        this._referLineFeature.display = false
      }
    }

  }

  /**
   * map读写器, 读取设置当前map
   *
   * @type {Function}
   * @property map
   * @param mapValue {Object} Datatang.map
   */
  get map() { return this._map }
  set map(mapValue) {
    if (this._mapRenderKey) {
      unlistenByKey(this._mapRenderKey)
      this._mapRenderKey = null
    }

    if (mapValue) {
      this._map = mapValue
      // this._mapRenderKey = listen(this, EventType.CHANGE, mapValue.render, mapValue)

      mapValue.addLayer(this._sketchLayer)
    }

    this._updateState()
  }

  /**
   * 更新绘制状态
   *
   * @method updateState
   * @private
   */
  _updateState() {
    const map = this.map
    const active = this.active
    if (!map || !active) {
      this._abortDrawing()
    }

    this._sketchLayer.map = map
  }

  /**
   * 获取默认绘制样式
   *
   * @method getDefaultStyleFunction
   * @returns {Function}
   */
  getDefaultStyleFunction() {
    const styles = Style.createDefaultEditing()
    return function (feature) {
      return styles[feature.geometry.geometryType]
    }
  }

  /**
   *
   * @returns {boolean}
   */
  shouldStopEvent() {
    // if (this._freehand) {
    //   return true
    // }

    return false
  }

  /**
   * 获取当前的Layer
   *
   * @method drawLayer
   * @return {null}
   */
  get drawLayer() { return this._drawLayer }

  set drawLayer(value) {
    this._drawLayer = value;
  }

  /**
   * 设置当前自由、绘制模式
   * @property freehand
   * @type {Boolean}
   */
  get freehand() { return this._freehand }
  set freehand(value) {
    this._freehand = value
  }
  /**
     * 设置 长按画框
     * @property freehand
     * @type {Boolean}
     */
  get longPress() { return this._longPress }
  set longPress(value) {
    this._longPress = value
  }
  /**
   * active读写器, 读取设置当前active非自由
   *
   * @type {Function}
   * @property active
   * @type {Boolean}
   */
  get active() { return this._active }
  set active(value) {
    this._active = value
    if (this._active === false) {
      if (this._sketchLayer) {
        this._sketchLayer.clear()
      }

      this._sketchPoint = null
    }
  }
}

/**
 * 获取当前绘制模式的静态方法
 *
 * @method getDrawMode
 * @param type {String}
 * @returns {Object}
 */
Draw.getDrawMode = function (type) {
  let drawMode = Draw.DrawMode.UNDEFINED

  switch (type) {
    case Geometry.POINT:
    case Geometry.MULTI_POINT:
      drawMode = Draw.DrawMode.POINT
      break
    case Geometry.LINE:
    case Geometry.MULTI_LINE:
      drawMode = Draw.DrawMode.LINE
      break
    case Geometry.POLYGON:
    case Geometry.MULTI_POLYGON:
    case Geometry.SQUAREX:
      drawMode = Draw.DrawMode.POLYGON
      break
    case Geometry.EXTENT:
      drawMode = Draw.DrawMode.EXTENT
      break
    case Geometry.CUBE:
      drawMode = Draw.DrawMode.CUBE
      break
    case Geometry.PARALLELOGRAM:
      drawMode = Draw.DrawMode.PARALLELOGRAM
      break
    case Geometry.TILTRECTANGLE:
      drawMode = Draw.DrawMode.TILTRECTANGLE
      break
  }

  return drawMode
}


/**
 * Draw mode.  This collapses multi-part geometry types with their single-part
 * cousins.
 *
 * 绘制模式：点、线、面、矩形(circle暂时不支持)
 * @enum {string}
 */
Draw.DrawMode = {
  POINT: 'Point',
  LINE: 'Line',
  POLYGON: 'Polygon',
  CIRCLE: 'Circle',
  EXTENT: 'Extent',
  CUBE: 'Cube',
  PARALLELOGRAM: 'Parallelogram',
  TILTRECTANGLE: 'TiltRectangle',
  TRAPEZIUM: 'Trapezium',
  SQUAREX: 'SquareX',
  UNDEFINED: 'undefined',
  ELLIPSE: Geometry.ELLIPSE
}
